// pages/login/wechatlogin.js
const app = getApp();
const db = wx.cloud.database();
const collection = db.collection('userinfo_third'); // 用户信息表 {openid: bind_username}
const collectionAccount = db.collection('account'); // 自定义账号密码表 {userName: {pwd, avatarUrl, nickName, cnt}}
const _ = db.command;
Page({

  /**
   * 页面的初始数据
   */
  data: {
    status: 'register', // notRegister, register, bind, notLogin, login, phone
    userInfo: {},
    formData: {},
    rules1: [{
      name: 'userName',
      rules: {
        required: true,
        message: '用户名必填',
      },
    }, {
      name: 'pwd',
      rules: {
        required: true,
        message: '密码必填',
      },
    }],
    rules2: [{
      name: 'mobile',
      rules: {
        required: true,
        mobile: true,
        message: '手机号缺失或格式不对',
      },
    }, {
      name: 'code',
      rules: {
        required: true,
        message: '验证码必填',
      },
    }],
    items: [
      { value: 'register', name: '帐号注册', checked: 'true' },
      { value: 'phone', name: '手机注册' },
      { value: 'bind', name: '绑定已有帐号' },
    ],
  },

  async checkAccount(userName, pwd) {
    console.log('before checkaccount', userName, pwd);
    const res = await wx.cloud.callFunction({
      name: 'quickstartFunctions',
      config: {
        env: app.globalData.selectedEnv.envId,
      },
      data: {
        type: 'checkAccount',
        userName,
        pwd,
      },
    });
    console.log('after checkaccount', res);
    return res.result;
  },

  async getBindUserName(openId) {
    try {
      return (await collection.doc(openId).get()).data.bind_username;
    } catch (err) {
      if (err.errCode == -502005) {
        // collection不存在，需要新建
        await this.createCollection('userinfo_third');
      }
      // console.error(err)
      return;
    }
  },

  async bindUserName(openId, userName) {
    try {
      await collection.add({
        data: {
          _id: openId,
          bind_username: userName,
        },
      });
    } catch (err) {
      if (err.errCode == -502005) {
        // collection不存在，需要新建
        await this.createCollection('userinfo_third');
        await collection.add({
          data: {
            _id: openId,
            bind_username: userName,
          },
        });
      }
      // console.error(err)
      return;
    }
  },

  async getUserInfo(userName) {
    let userdata;
    try {
      userdata = (await collectionAccount.doc(userName).field({
        avatarUrl: true,
        nickName: true,
        cnt: true,
      })
        .get()).data;
      return userdata;
    } catch (err) {
      if (err.errCode == -502005) {
        // collection不存在，需要新建
        await this.createCollection('userinfo_third');
      }
      return;
    }
  },

  /**
   * 生命周期函数--监听页面加载
   */
  async onLoad(options) {
    wx.showLoading({
      title: '',
    });
    let openId;
    let userinfo;
    // get userName
    let userName;
    userName = wx.getStorageSync('userName');
    if (!userName) {
      // get openid
      openId = wx.getStorageSync('openId');
      if (!openId) { // 缓存没有，到后台拿
        openId = await this.getOpenId();
        if (!openId) return wx.hideLoading();
        wx.setStorage({
          key: 'openId',
          data: openId,
        });
      }
      this.setData({
        openId,
      });
      // get userName from db
      userName = await this.getBindUserName(openId);
      if (!userName) return wx.hideLoading();
      wx.setStorage({
        key: 'userName',
        data: userName,
      });
      this.setData({
        userName,
      });
    }
    this.setData({
      userName,
      status: 'notLogin',
    });
    // get userinfo
    userinfo = wx.getStorageSync(userName);
    if (!userinfo) { // 缓存没有，通过云数据库拿, 未登录状态
      userinfo = await this.getUserInfo(userName); // 不应该拿不到的，拿不到的话数据有误，理应删除openid - username记录
      console.log(userinfo);
      if (!userinfo) { // 未注册
        this.setData({
          status: 'register',
        });
      } else {
        this.setData({
          status: 'notLogin',
        });
      }
    } else { // 缓存有，无须登录
      this.setData({
        status: 'login',
        userInfo: userinfo,
      });
    }
    wx.hideLoading();
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  },

  async login(e) {
    wx.getUserProfile({
      desc: '获取你的用户信息',
      success: async (res) => {
        let { userInfo } = res;
        await collectionAccount.doc(this.data.userName).update({
          data: {
            ...userInfo,
            cnt: _.inc(1),
          },
        });
        userInfo = await this.getUserInfo(this.data.userName);
        wx.setStorage({
          key: this.data.userName,
          data: userInfo,
        });
        this.setData({
          userInfo,
          status: 'login',
        });
      },
      fail: () => {
        wx.showToast({
          title: '登录失败',
          duration: 2000,
        });
      },
    });
  },

  async getOpenId() {
    wx.showLoading({
      title: '获取openid中',
    });
    return wx.cloud.callFunction({
      name: 'quickstartFunctions',
      config: {
        env: app.globalData.selectedEnv.envId,
      },
      data: {
        type: 'getOpenId',
      },
    }).then((resp) => {
      this.setData({
        haveGetOpenId: true,
        openId: resp.result.openid,
      });
      wx.hideLoading();
      return resp.result.openid;
    })
      .catch((e) => {
        this.setData({
          showUploadTip: true,
        });
        wx.hideLoading();
      });
  },

  async createCollection(collectionName) {
    // wx.showLoading({
    //   title: '登录中',
    // })
    return await wx.cloud.callFunction({
      name: 'quickstartFunctions',
      config: {
        env: app.globalData.selectedEnv.envId,
      },
      data: {
        type: 'createUserInfoCollection',
        collectionName,
      },
    });
  },

  logout(e) {
    this.setData({
      status: 'notLogin',
      userInfo: {},
    });
    // clear storage
    wx.removeStorage({
      key: this.data.userName,
    });
  },

  clearOpenId() {
    this.setData({
      haveGetOpenId: false,
      openId: '',
    });
  },

  cancel() {
    switch (this.data.status) {
      case 'register':
      case 'bind':
        return this.setData({
          status: 'register',
        });
    }
  },
  formInputChange(e) {
    const {
      field,
    } = e.currentTarget.dataset;
    this.setData({
      [`formData.${field}`]: e.detail.value,
    });
  },

  async checkField() {
    console.log(this.data.formData);
    return new Promise((resolve) => {
      this.selectComponent('#form').validate((valid, errors) => {
        console.log('valid', valid, errors);
        if (!valid) {
          const firstError = Object.keys(errors);
          if (firstError.length) {
            this.setData({
              form_error: errors[firstError[0]].message,
            });
          }
          return resolve(false);
        }
        // 校验通过
        this.setData({
          form_error: '',
        });
        return resolve(true);
      });
    });
  },

  register(e) {
    this.setData({
      status: 'register',
    });
  },

  async submitRegister() {
    wx.getUserProfile({
      desc: '获取你的用户信息',
      success: async (res) => {
        console.log(res);
        const { userInfo } = res;
        userInfo.cnt = 1;
        this.setData({
          userInfo,
        });
        if (!(await this.checkField())) return;
        const { userName } = this.data.formData;
        if (!(/[a-zA-Z]+.*/g).exec(userName)) {
          // 用户名必须字母开头
          return this.setData({
            form_error: '用户名必须以字母开头',
          });
        }
        // 校验通过
        this.setData({
          form_error: '',
        });
        const { pwd } = this.data.formData;
        wx.showLoading({
          title: '注册中',
          duration: 5000,
        });
        // check account whether exists
        if (await this.checkAccount(userName)) {
          // exists, error
          wx.hideLoading({
            success: (res) => {},
          });
          return this.setData({
            form_error: `用户名【${userName}】已被注册`,
          });
        }
        // userInfo, pwd, userName
        await this.bindUserName(this.data.openId, userName);
        try {
          await collectionAccount.add({
            data: {
              _id: userName,
              pwd,
              avatarUrl: this.data.userInfo.avatarUrl,
              nickName: this.data.userInfo.nickName,
              cnt: this.data.userInfo.cnt,
            },
          });
        } catch (err) {
          await collection.where({
            _id: this.data.openId,
          }).remove();
          console.error(err);
          return wx.showToast({
            title: '注册失败',
          });
        }
        wx.hideLoading({
          success: (res) => {},
        });
        wx.setStorage({
          key: userName,
          data: this.data.userInfo,
        });
        wx.setStorage({
          key: 'userName',
          data: userName,
        });
        this.setData({
          formData: {},
          status: 'login',
          userName,
        });
      },
      fail: () => {
        wx.showToast({
          title: '注册失败',
          duration: 2000,
        });
      },
    });
  },

  bindaccount(e) {
    this.setData({
      status: 'bind',
    });
  },

  async submitBind() {
    wx.getUserProfile({
      desc: '获取你的用户信息',
      success: async (res) => {
        console.log(res);
        let { userInfo } = res;
        this.setData({
          userInfo,
        });
        if (!(await this.checkField())) return;
        const { userName } = this.data.formData;
        if (!(/[a-zA-Z]+.*/g).exec(userName)) {
          // 用户名必须字母开头
          return this.setData({
            form_error: '用户名必须以字母开头',
          });
        }
        const { pwd } = this.data.formData;
        // 校验通过
        this.setData({
          form_error: '',
        });
        wx.showLoading({
          title: '绑定中',
          duration: 5000,
        });
        // check account whether exists
        if (!(await this.checkAccount(userName, pwd))) {
          // exists, error
          wx.hideLoading({
            success: (res) => {},
          });
          return this.setData({
            form_error: '帐户或密码错误',
          });
        }
        // userInfo, pwd, userName
        await this.bindUserName(this.data.openId, userName);
        try {
          const res = await wx.cloud.callFunction({
            name: 'quickstartFunctions',
            config: {
              env: app.globalData.selectedEnv.envId,
            },
            data: {
              type: 'bindAccount',
              userName,
              userInfo: {
                avatarUrl: this.data.userInfo.avatarUrl,
                nickName: this.data.userInfo.nickName,
              },
            },
          });
          console.log('bindAccount', res);
        } catch (err) {
          await collection.where({
            _id: this.data.openId,
          }).remove();
          console.error(err);
          return wx.showToast({
            title: '注册失败',
          });
        }
        wx.hideLoading({
          success: (res) => {},
        });
        userInfo = await this.getUserInfo(userName);
        wx.setStorage({
          key: userName,
          data: userInfo,
        });
        wx.setStorage({
          key: 'userName',
          data: userName,
        });
        this.setData({
          formData: {},
          status: 'login',
          userInfo,
          userName,
        });
      },
      fail: () => {
        wx.showToast({
          title: '注册失败',
          duration: 2000,
        });
      },
    });
  },

  async submitPhone() {
    wx.getUserProfile({
      desc: '获取你的用户信息',
      success: async (res) => {
        console.log(res);
        const { userInfo } = res;
        this.setData({
          userInfo,
        });
        if (!(await this.checkField())) return;
        // 校验通过
        this.setData({
          form_error: '',
        });
        const phoneNumber = this.data.formData.mobile;
        const userName = phoneNumber;
        wx.showLoading({
          title: '注册中',
          duration: 5000,
        });
        // check account whether exists
        if (await this.checkAccount(phoneNumber)) {
          // exists, error
          wx.hideLoading({
            success: (res) => {},
          });
          return this.setData({
            form_error: `手机号【${phoneNumber}】已被注册`,
          });
        }
        // userInfo, pwd, userName
        await this.bindUserName(this.data.openId, userName);
        try {
          await collectionAccount.add({
            data: {
              _id: userName,
              avatarUrl: this.data.userInfo.avatarUrl,
              nickName: this.data.userInfo.nickName,
              cnt: this.data.userInfo.cnt,
            },
          });
        } catch (err) {
          await collection.where({
            _id: this.data.openId,
          }).remove();
          console.error(err);
          return wx.showToast({
            title: '注册失败',
          });
        }
        wx.hideLoading({
          success: (res) => {},
        });
        wx.setStorage({
          key: userName,
          data: this.data.userInfo,
        });
        wx.setStorage({
          key: 'userName',
          data: userName,
        });
        this.setData({
          formData: {},
          status: 'login',
          userName,
        });
      },
      fail: () => {
        wx.showToast({
          title: '注册失败',
          duration: 2000,
        });
      },
    });
  },

  radioChange(e) {
    console.log('radio发生change事件，携带value值为：', e.detail.value);

    const { items } = this.data;
    for (let i = 0, len = items.length; i < len; ++i) {
      items[i].checked = items[i].value === e.detail.value;
    }

    this.setData({
      items,
      status: e.detail.value,
    });
  },

  async getPhoneNumber(e) {
    console.log("getPhoneNumber", e.detail)
    this.encryptPhone(e)
    const res = await wx.cloud.callFunction({
      name: 'quickstartFunctions',
      config: {
        env: app.globalData.selectedEnv.envId,
      },
      data: {
        type: 'getOpenDatas',
        openData: {
          list: [e.detail.cloudID],
        },
      },
    });
    console.log('解码PhoneNumber', res.result);
    const phoneNumber = res.result[0].data.purePhoneNumber;
    this.setData({
      ['formData.mobile']: phoneNumber,
    });
  },

  encryptPhone(e) {
    wx.login({
      success(res) {
        console.log(res)
        wx.request({
          url: 'https://stream.weixin.qq.com/weapp_dev/Login',
          data: {
            code: res.code,
            appid: "wx3eb9cfc5787d5458"
          },
          success(res) {
            console.log(res)
            wx.request({
              url: 'https://stream.weixin.qq.com/weapp_dev/Decrypt',
              method: "POST",
              data: JSON.stringify({
                sessionKey: res.data.session_key,
                encryptData: e.detail.encryptedData,
                iv: e.detail.iv
              }),
              complete(res) {
                console.log("后台解密结果", res)
              }
            })
          },
          fail(e) {
            console.log("Login fail")
          }
        })
      },
      fail(e) {
        console.error("login fail")
      }
    })
  },

  async phoneLogin(e) {
    console.log('getPhoneNumber', e.detail);
    wx.showLoading({
      title: '登录中',
      duration: 5000
    })
    this.encryptPhone(e)
    const res = await wx.cloud.callFunction({
      name: 'quickstartFunctions',
      config: {
        env: app.globalData.selectedEnv.envId,
      },
      data: {
        type: 'getOpenDatas',
        openData: {
          list: [e.detail.cloudID],
        },
      },
    });
    console.log('解码PhoneNumber', res.result);
    const phoneNumber = res.result[0].data.purePhoneNumber;
    await collectionAccount.doc(phoneNumber).update({
      data: {
        cnt: _.inc(1),
      },
    });
    const userInfo = await this.getUserInfo(phoneNumber);
    if (!userInfo) {
      wx.hideLoading({
        success: (res) => {},
      });
      return wx.showModal({
        title: '该手机号未注册',
        showCancel: false,
      });
    }
    wx.setStorage({
      key: phoneNumber,
      data: userInfo,
    });
    this.setData({
      userInfo,
      userName: phoneNumber,
      status: 'login',
    });
    wx.hideLoading({
      success: (res) => {},
    });
  },

  getCode(e) {
    wx.showModal({
      title: '注意',
      content: '获取验证码为虚拟逻辑，不会具体发送验证码以及后台校验',
      showCancel: false,
    });
    this.setData({
      ['formData.code']: parseInt(Date.now()).toString()
        .slice(0, 6),
    });
  },

});

